package org.example.utils;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.amazonaws.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.web.servlet.HandlerMapping;
import org.apache.commons.io.IOUtils;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.Iterator;
import java.util.Map;

/**
 * request 请求参数解析工具
 *
 * @author jw.z
 * @date 2022/6/9 11:13
 */
public class RequestParseParamsTool {

    private static final Logger log = LoggerFactory.getLogger(RequestParseParamsTool.class);

    private RequestParseParamsTool() {
    }

    /**
     * 判断请求参数是否转换为json格式
     *
     * @param request
     * @return
     */
    private static boolean isConvertJSON(HttpServletRequest request) {
        String contentType = request.getContentType();
        //有contentType  && json格式，  get请求不转换
        if (contentType != null
                && contentType.toLowerCase().contains("application/json")
                && !request.getMethod().equalsIgnoreCase("GET")
        ) { //application/json 需要转换为json格式；
            return true;
        }
        return false;
    }

    /**
     * 获取JSON 形式参数 从 请求体中
     * 支持获取application/json 和 form 表单
     *
     * 说明: 支持GET请求时，URL参数解析
     * @param request
     * @return
     */
    public static JSONObject getParamsFromRequestBody(HttpServletRequest request) {
        if (isConvertJSON(request)) {
            return JSON.parseObject(fetchRequestJsonBody(request));
        }
        return parseParamsFromBody(request);
    }

    /**
     * 解析请求行数据
     *
     * @param request
     * @return
     */
    public static Map<String, String> parseUrlParams(HttpServletRequest request) {
        String queryString = request.getQueryString();
        return MapUrlParamsTool.getUrlParams(queryString);
    }

    /**
     * 解析请求头数据
     *
     * @param request
     * @return
     */
    public static JSONObject parseHeadParamsFromBody(HttpServletRequest request, String... headName) {
        JSONObject returnObject = new JSONObject();
        for (int i = 0; i < headName.length; i++) {
            String headValue = request.getHeader(headName[i]);
            returnObject.put(headName[i], headValue);
        }
        return returnObject;
    }

    /**
     * 解析JSON请求数据 (该方案存在bug, 咱不推荐使用, 保留是为了定位)
     * content-type=application/json
     *
     * @param request
     * @return
     */
    public static JSONObject parseJsonParamsFromBody(HttpServletRequest request) {
        JSONObject returnObject = new JSONObject();
        StringBuilder sb = new StringBuilder();
        String body = "";
        try {
            body = IOUtils.toString(request.getInputStream(), StandardCharsets.UTF_8);
//            body = fetchRequestJsonBody(request);
//            BufferedReader bufferedReader = request.getReader();
//            String str;
//            while ((str = bufferedReader.readLine()) != null) {
//                sb.append(str);
//            }
//            body = sb.toString();
            if (!StringUtils.isNullOrEmpty(body)) {
                returnObject = JSON.parseObject(body);
            }
        } catch (Exception e) {
            log.error("请求参数转换异常！ params=[{}]", body);
        }
        /*Map<String, String> urlParams = parseUrlParams(request);
        for (String key: urlParams.keySet()) {
            returnObject.put(key, urlParams.get(key));
        }*/
        return returnObject;
    }

    /**
     * 获取application/json 请求体数据
     *
     * @return
     */
    public static String fetchRequestJsonBody(HttpServletRequest request) {
        if (!isConvertJSON(request)) {
            return null;
        }
        String reqStr = null;
        BufferedReader streamReader = null;
        try {
            streamReader = new BufferedReader(new InputStreamReader(request.getInputStream(), StandardCharsets.UTF_8));
            StringBuilder responseStrBuilder = new StringBuilder();
            String inputStr;
            while ((inputStr = streamReader.readLine()) != null) {
                responseStrBuilder.append(inputStr);
            }
            reqStr = responseStrBuilder.toString();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (streamReader != null) {
                    streamReader.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return reqStr;
    }

    /**
     * 获取body体里面nultipart/form-data 请求体数据
     * content-type=anultipart/form-data
     *
     * @param request
     * @return
     */
    public static JSONObject parseJsonParamsFromUrl(HttpServletRequest request) {
        JSONObject returnObject = new JSONObject();
        Map<String, String> urlParams = parseUrlParams(request);
        for (String key: urlParams.keySet()) {
            returnObject.put(key, urlParams.get(key));
        }
        return returnObject;
    }

    /**
     * 解析表单请求体数据
     *
     * 说明: 支持GET请求时，URL参数解析
     *
     * @param request
     * @return
     */
    public static JSONObject parseParamsFromBody(HttpServletRequest request) {
        JSONObject returnObject = new JSONObject();
        // 参数Map
        Map<String, String[]> parameterMap = request.getParameterMap();
        // 返回值Map
        Iterator<Map.Entry<String, String[]>> entries = parameterMap.entrySet().iterator();
        Map.Entry<String, String[]> entry;
        String name;
        String value = "";
        while (entries.hasNext()) {
            entry = entries.next();
            name = entry.getKey();
            Object valueObj = entry.getValue();
            if (null == valueObj) {
                value = "";
            } else {
                String[] values = (String[]) valueObj;
                for (String s : values) {
                    value = s + ",";
                }
                value = value.substring(0, value.length() - 1);
            }
            if (!name.contains("[")) {
                returnObject.put(name, value);
                continue;
            }
            /*
                添加对json对象解析的支持 {ps[abc] : 1}
             */
            String mainKey = name.substring(0, name.indexOf("["));
            String subKey = name.substring(name.indexOf("[") + 1, name.indexOf("]"));
            JSONObject subJson = new JSONObject();
            if (returnObject.get(mainKey) != null) {
                subJson = (JSONObject) returnObject.get(mainKey);
            }
            subJson.put(subKey, value);
            returnObject.put(mainKey, subJson);
        }
        return returnObject;
    }

    /**
     * 获取path variable（对应@PathVariable）
     */
    public static String[] getPathVariable(HttpServletRequest request) {
        String[] paths = null;
        ServletWebRequest webRequest = new ServletWebRequest(request, null);
        Map<String, String> uriTemplateVars = (Map<String, String>) webRequest.getAttribute(
                HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE, RequestAttributes.SCOPE_REQUEST);
        if (!CollectionUtils.isEmpty(uriTemplateVars)) {
            paths = uriTemplateVars.values().toArray(new String[]{});
        }
        return paths;
    }


}
